#ifndef __DRIVER_PIN_H__
#define __DRIVER_PIN_H__

struct pin_ops;

struct pin {
	struct device parent;
	struct pin_ops *ops;
};

enum pin_mode {
	PIN_MODE_OUTPUT,
	PIN_MODE_INPUT,
	PIN_MODE_OUTPUT_OD,
	PIN_MODE_AF_PP,
	PIN_MODE_AF_OD,
	PIN_MODE_INPUT_PULL_UP,
	PIN_MODE_INPUT_PULL_DOWN,
	PIN_MODE_UNKOWN,
};

enum pin_irq_mode {
	PIN_IRQ_MODE_FALLING,
	PIN_IRQ_MODE_RISING,
	PIN_IRQ_MODE_RISING_FALLING,
	PIN_IRQ_MODE_UNKNOWN,
};

struct pin_ops {
	base_t (*read)  (const base_t pin);
	err_t  (*write) (const base_t pin, const base_t value);
	err_t  (*mode)  (const base_t pin, const enum pin_mode mode);
	err_t  (*attach_irq) (const base_t pin,
				const enum pin_irq_mode mode,
				void (*handler)(void *args),
				void *args,
				uint8_t priority);
	err_t  (*detach_irq) (const base_t pin);
	err_t  (*enable_irq) (const base_t pin, const uint8_t enable);
	base_t (*pin_get) (const char *pin_name);
};

struct device_pin_status {
	base_t status;
	base_t pin;
};

struct pin_irq_handler {
	base_t     pin;
	uint16_t   mode;
	void       *args;
	void (*handler)(void *args);
	uint8_t     priority;
};

extern err_t hw_pin_register(const char *name, struct pin_ops *ops,
			void *private_data);

extern base_t hw_pin_get(const char *name);

extern base_t hw_pin_read(const base_t pin_num);

extern err_t hw_pin_write(const base_t pin_num,
			const base_t value);

extern err_t hw_pin_mode(const base_t pin_num,
			const enum pin_mode mode);

extern err_t hw_pin_attach_irq(const base_t pin_num,
			const enum pin_irq_mode mode,
			void (*handler)(void *args),
			void *args,
			uint16_t priority);

extern err_t hw_pin_detach_irq(const base_t pin_num);

extern err_t hw_pin_irq_enable(const base_t pin_num,
			const uint8_t enable);

#endif /* __DRIVER_PIN_H__ */
